<template>
  <vxe-grid ref='xGrid' v-bind="gridOptions"
    @checkbox-change="checkboxChange"
    @checkbox-all="checkboxAll"
    @checkbox-range-change="checkboxRangeChange">
      <template #form>
        <slot name="form"></slot>
      </template>

      <template #tools_>
        <!-- <span style="margin-right: .7rem;">
          <vxe-button circle icon="vxe-icon-setting"></vxe-button>
        </span> -->
      </template>

      <!-- left -->
      <template #toolbar_buttons>
        <slot name="topLeft1"></slot>
        <Divider type="vertical"/>
        <!-- <span v-for="(v, i) in buttons.topLeft" :key="`i-${i}`">
          <Popconfirm v-if="v.tip" placement="top"
            :disabled="batchDeleteDisabled"
            :title="v.tipContent"
            @confirm="handleCall(v)">
            <template v-if="v.disable === 2" #icon><QuestionCircleOutlined style="color: red" /></template>
            <vxe-button v-if="v.disable === 2" :status="parseButtonConf(v)?.status"  :disabled="batchDeleteDisabled">{{v.name}}{{checkboxCount}}</vxe-button>
            <vxe-button v-else-if="v.disable === 1" :status="parseButtonConf(v)?.status" :disabled="oneDisabled">{{v.name}}</vxe-button>
            <vxe-button v-else :status="parseButtonConf(v)?.status" :disabled="oneDisabled">{{v.name}}</vxe-button>
          </Popconfirm>
          <span v-else>
            <vxe-button v-if="v.disable > 0" :status="parseButtonConf(v)?.status" :disabled="oneDisabled" @click="handleCall(v)">{{v.name}}</vxe-button>
            <vxe-button v-else :status="parseButtonConf(v)?.status"  @click="handleCall(v)">{{v.name}}</vxe-button>
          </span>
          <Divider type="vertical"/>
        </span> -->
        <span v-for="(v, i) in buttons.topLeft" :key="`i-${i}`" style="margin-right: 1rem;">
          <Divider v-if="i !== 0" type="vertical"/>
          <Popconfirm v-if="v.tip"
            placement="top"
            :title="v.tipContent"
            @confirm="handleCall(v)">
            <vxe-button>{{v.name}}</vxe-button>
          </Popconfirm>
          <vxe-button v-else-if="v.selectedCount!==1" @click="handleCall(v)">{{v.name}}</vxe-button>
          <vxe-button v-else @click="handleCall(v)">{{v.name}} {{checkboxCount}}</vxe-button>
        </span>

        <slot name="topLeft2"></slot>
      </template>

      <!-- operate -->
      <template #operate="{ row }">
        <div class="table-operate">
          <div v-for="(v, i) in buttons.inner" :key="`i-${i}`">
            <Divider v-if="i !== 0" type="vertical"/>
            <span v-if="innerOptShow(row, v)">
              <Popconfirm v-if="v.tip"
                placement="top"
                :title="v.tipContent"
                @confirm="handleCall(v, row)">
                <a>{{v.name}}</a>
              </Popconfirm>
              <a v-else @click="handleCall(v, row)">{{v.name}}</a>
            </span>
          </div>
        </div>
      </template>

      <template #expandRow="{row}">
        <slot name="expandRowContent" :row="row"></slot>
      </template>
  </vxe-grid>
</template>
<script lang="ts" name="XGrid" setup>
import { Divider, Popconfirm } from 'ant-design-vue';
import { toLower } from 'lodash-es';
import { computed, reactive, ref, toRaw, watch, watchPostEffect, } from 'vue';
import { useRoute } from 'vue-router';
import { VxeGridPropTypes, VxeGridProps, VxeTablePropTypes, } from 'vxe-table';
import { pagerConfig } from './data';
import { defHttp } from '/@/utils/http/axios';
// import { usePermission } from '/@/hooks/web/usePermission';

// const { hasPermission } = usePermission();

const buttons = reactive({
  topLeft: [] as any[],
  // topRight: [] as any [],
  inner: [] as any[],
})

const props = defineProps({
  baseUrl: {type: String, default: '',},
  delUrl: {type: String, default: '',},
  size: { type: String, default: 'small' }, // null | 'medium' | 'small' | 'mini'
  isTree: { type: Boolean, default: false },
  columns: { type: Array, default: () => [],},
  queryParams: {type: Object, default: {},},
  height: { type: [Number, String] as PropType<Number | String>, default: window.innerHeight - 103},
  border: {type: [String, Boolean], default: 'full'}, // default | full | outer | inner | none
  line: {type: Boolean, default: true},
  expandAll: {type: Boolean, default: true},
  stripe: {type: Boolean, default: true},
  showOverflow: {type: [String, Boolean], default: 'tooltip'}, // ellipsis | title | tooltip
  notCheckbox: {type: Array<Number | String>, default: () => null},
  checkStrictly: {type: Boolean, default: false,},
  optFixed: {type: [String, null] as PropType<String | null>, default: 'left',}, // left | right | null
  notButtons: {type: Array, default: []},
  printTop: { type: String, default: '' },
  printBottom: { type: String, default: '' },
  printStyle: { type: String, default: '' },
  footerMethod: Function,
  isSheet: {type: Boolean, default: false,},
  queryApi: Function,
  queryAllApi: Function,
  deletesApi: Function,
})

const route = useRoute();
const url = computed(() => {
  let result = ''
  if (props.baseUrl) {
    result = props.baseUrl
  } else {
    result = '/' + toLower(route.name?.toString())
  }
  return result;
})

const insideQueryParams = ref();
const xGrid = ref()
const gridOptions = reactive<VxeGridProps>({
  border: props.border as VxeTablePropTypes.Border,
  resizable: true,
  round: true,
  showHeaderOverflow: true,
  showOverflow: props.showOverflow as VxeTablePropTypes.ShowOverflow,
  highlightHoverRow: true,
  keepSource: true,
  showFooter: !!(props.footerMethod),
  id: 'ID',
  stripe: props.stripe,
  height: props.height as VxeTablePropTypes.Height,
  size: props.size as VxeTablePropTypes.Size,
  // columns: [...props.columns, 
  //         {title: '操作', sortable: false, visible: true, slots: {default: 'operate'}, 
  //         width: 80, align: 'center', fixed: props.optFixed,}] as VxeGridPropTypes.Columns,
  columns: (() => {
    return [
    ...props.columns.slice(0, 1),
    {title: '操作', sortable: false, visible: true, slots: {default: 'operate'}, width: 80, align: 'center', fixed: props.optFixed,},
    ...props.columns.slice(1),
    ] as VxeGridPropTypes.Columns
  })(),
  columnConfig: {
    useKey: true,
    isCurrent: true,
    isHover: true,
  },
  rowConfig: {
    useKey: true,
    isCurrent: true,
    isHover: false,
    keyField: 'ID',
  },
  // mouseConfig:{selected: false,},
  keyboardConfig: {isArrow: true, isEnter: true,},
  expandConfig: {
    expandAll: true,
    trigger: 'cell',
  },
  customConfig: {
    storage: true,
  },
  tooltipConfig: {
  },
  printConfig: {
    sheetName: '',
    mode: 'selected',
    style: props.printStyle,
    modes: ['current', 'selected', 'all'],
    columnFilterMethod: ({ column, }) => {
      return column.type !== 'checkbox';
    },
    beforePrintMethod: ({ content, options }) => {
      let result = props.printTop + content + props.printBottom;
      // result = `<div style="width:100%">` + result + `</div>`
      return result;
    }
  },
  sortConfig: {
    trigger: 'cell',
    remote: false
  },
  filterConfig: {
    remote: false
  },
  pagerConfig: pagerConfig,
  toolbarConfig: {
    slots: {
      buttons: 'toolbar_buttons',
      tools: 'tools_'
    },
  },
  importConfig: {
  },
  exportConfig: {
    remote: false,
    types: ['xlsx'],
    modes: ['current', 'selected', 'all'],
  },
  checkboxConfig: {
    reserve: false,
    highlight: true,
    range: true,
    trigger: 'cell',
    checkStrictly: props.checkStrictly,
    checkMethod: ({row}) => {
      if (props.isSheet) {
        return !(row?.status === 4) // 关闭订单不能操作
      }
      if (props.notCheckbox) {
        return !(props.notCheckbox.some((e:number) => e === row.id))
      }
      return true;
    },
  },
  footerMethod: ({columns, data,}) => {
    if (props.footerMethod) {
      return props.footerMethod({columns, data,})
    }
    return [];
  },
  proxyConfig: {
    autoLoad: true,
    ajax: {
      // { page, sort, sorts, filters, form }
      query({ page, }) {
        // batchDeleteDisabled.value = true
        // let query = Object.assign({}, toRaw(props.queryParams), page)
        // let url_ = props.isTree ? `${url.value}/list` : `${url.value}/table`
        // return defHttp.get<any>({ url: url_, params: query });

        if (props.queryApi) {
          let params = Object.assign({}, toRaw(props.queryParams), page)
          return props.queryApi(params)
        }
      },
      // { sort, sorts, filters, form }
      queryAll() {
        // let query = Object.assign({}, toRaw(props.queryParams),)
        // return defHttp.get<any>({ url: `${url.value}/list`, params: query });
        if (props.queryAllApi) {
          let params = Object.assign({}, toRaw(props.queryParams),)
          return props.queryAllApi(params)
        }
      }
    }
  },
});

let { buttonList } = route.meta
if (buttonList) {
  if (props.notButtons.length > 0) { // 移除特定页面不显示的按钮
    // remove(buttonList, function(e) {
    //   return props.notButtons.some((nb:any) => nb.name === e.name)
    // })
  }

  buttons.topLeft = buttonList.filter(e => e.place === 0 && !props.notButtons.some((nb:any) => nb.name === e.name))
  buttons.inner = buttonList.filter(e => e.place === 2 && !props.notButtons.some((nb:any) => nb.name === e.name))

  let topRight = buttonList.filter(e => e.place === 1 && !props.notButtons.some((nb:any) => nb.name === e.name))
  topRight.forEach(e => {
    if (e.name === '刷新表') gridOptions!.toolbarConfig!.refresh = true;
    if (e.name === '导入') gridOptions!.toolbarConfig!.import = true;
    if (e.name === '导出') gridOptions!.toolbarConfig!.export = true;
    if (e.name === '打印') gridOptions!.toolbarConfig!.print = true;
    if (e.name === '最大化') gridOptions!.toolbarConfig!.zoom = true;
    if (e.name === '自定义列') gridOptions!.toolbarConfig!.custom = true;
  })
}

const checkboxCount = ref(' (0)')
watchPostEffect(() => {
  if (xGrid.value) {
    checkboxCount.value = ` (${xGrid.value.getCheckboxRecords(true).length})`

    let innerLen = buttons.inner.length
    let opt = xGrid.value.getColumns().find((e:any) => e?.title === '操作')
    if (opt) {
      if (innerLen > 0 && props.columns.length > 0) {
        let width = 80
        if (innerLen > 1) {
          width = 70 * innerLen * 0.9;
        }
        opt.width = width
      } else {
        opt.visible = false
      }
    }
    xGrid.value.refreshColumn()
  }

  if (props.isTree && !gridOptions.treeConfig) { // 防止一直设置
    gridOptions.treeConfig = {
      rowField: 'id',
      // parentField: 'parentId',
      trigger: 'cell',
      lazy: false,
      accordion: false,
      showLine: props.line,
      expandAll: props.expandAll,
    }
    gridOptions!.checkboxConfig!.range = false;
    delete gridOptions.pagerConfig
  }
})

watch(() => props.queryParams, (v1, _) => {
  insideQueryParams.value = v1
}, {
  immediate: true,
  deep: true
})

const innerOptShow = computed(() => (row:any, btn:any) => {
  // if (props.isSheet) {
  //   switch(row.status) {
  //     case 1: return true
  //     case 2: return btn.name !== '编辑'
  //     case 4: return btn.name !== '关闭'
  //     default: true
  //   }
  // }
  return true
})

const reload = (isReset?:boolean) => {
  batchDeleteDisabled.value = true
  oneDisabled.value = true
  gridOptions.loading = true

  let params = {}
  if (!isReset) {
    params = Object.assign({}, toRaw(insideQueryParams.value),)
  }
  if (props.queryApi) {
    props.queryApi(params).then(dd => {
      if (props.isTree) {
        xGrid.value.reloadData(dd)
      } else {
        xGrid.value.reloadData(dd?.result)
        let {pager} = xGrid.value.getProxyInfo()
        pager.total = dd?.page?.total
      }
    }).finally(() => {
      gridOptions.loading = false
      // insideQueryParams.value = {}
    })
  }
}

const handleDelete = (...params: number[]) => {
  console.log(params)
  if (params.length > 0) {
    if (props.deletesApi) {
      props.deletesApi(params).then(() => {
        batchDeleteDisabled.value = true
        reload()
      })
    } else {
      defHttp.delete({url: props.delUrl || url.value, data: params}).then(() => {
        batchDeleteDisabled.value = true
        reload()
      })
    }
  }
}
const handleBatchDelete = () => {
  let checkedList = xGrid.value.getCheckboxRecords(true).map((e:any) => e.ID) || []
  handleDelete(...checkedList)
}

const batchDeleteDisabled = ref(true)
const oneDisabled = ref(true)
const checkedRowRef = ref() // 单行选中的数据
function setCheckedRowRef (list:any[]) {
  if (list.length === 1) {
      checkedRowRef.value = toRaw(list[0])
      oneDisabled.value = false
  } else {
    checkedRowRef.value = null
    oneDisabled.value = true
  }
}
const checkboxChange = ({}) => {
  let checkedList = xGrid.value.getCheckboxRecords(true)
  setCheckedRowRef(checkedList)
  batchDeleteDisabled.value = !(checkedList.length > 0)
  emits('checked-count', checkedList.length)
}
const checkboxAll = ({ checked,}) => {
  setCheckedRowRef([])
  batchDeleteDisabled.value = !checked
  emits('checked-count', xGrid.value.getCheckboxRecords(true).length)
}
const checkboxRangeChange = ({}) => {
  let checkedList = xGrid.value.getCheckboxRecords(true)
  setCheckedRowRef(checkedList)
  batchDeleteDisabled.value = !(checkedList.length > 0)
  emits('checked-count', checkedList.length)
}

const parseButtonConf = (btn:any) => {
  if (!btn.otherConf) return {}
  try {
    let otherConf = JSON.parse(`${btn.otherConf}`)
    return otherConf
  } catch(e) {
    console.error(e)
    return {}
  }
}

console.log(buttonList?.map(e => e.func).filter(Boolean))
const emits = defineEmits([])

// const emits = defineEmits([
//   'see-details',
//   'create', 'edit', 'copy', 'grant', 'checked-count', 'resetPassword',
//   'verify', 'unVerify', 'close', 'test',
//   'to-void', 'invt-in', 'invt-batch-in', 'invt-out', 'invt-batch-out']);
// const funcMap: Map<String, Function> = new Map([
//   ['seeDetails', (row:any) => emits('see-details', row)],
//   ['create', () => emits('create')],
//   ['edit', (row:any) => emits('edit', row)],
//   ['batchDelete', handleBatchDelete],
//   ['copy', (row:any) => emits('copy', row)],
//   ['grant', (row:any) => emits('grant', row)],
//   ['resetPassword', (row:any) => emits('resetPassword', row)],
//   ['verify', (list:any) => emits('verify', list)],
//   ['unVerify', (list:any) => emits('unVerify', list)],
//   ['close', (row:any) => emits('close', row)],
//   ['toVoid', (row:any) => emits('to-void', row)],
//   ['invtIn', (row:any) => emits('invt-in', row)],
//   ['invtBatchIn', (list:any) => emits('invt-batch-in', list)],
//   ['invtOut', (row:any) => emits('invt-out', row)],
//   ['invtBatchOut', (list:any) => emits('invt-batch-out', list)],
// ]);
// 调用
const handleCall = (btn:any, row?:any) => {
  let funcName = btn?.func
  console.log(btn, row)
  emits(funcName as never, row)
  // if (funcName !== '-') {
  //   let func = funcMap.get(funcName)
  //   if (func) {
  //     if (btn?.disable === 2) {
  //       func(toRaw(xGrid.value.getCheckboxRecords(true)).filter((e:any) => e.status !== 4))
  //     } else {
  //       if(row) func(row)
  //       else func(checkedRowRef.value)
  //     }
  //   }
  // }
}

defineExpose({
  reload,
  setAllTreeExpand(expand:boolean) {
    xGrid.value.setAllTreeExpand(expand)
  },
  getCheckedList():any[] {
    return xGrid.value.getCheckboxRecords(true)
  },
  clearCheckboxRow() {
    xGrid.value.clearCheckboxRow()
  }
})
</script>
<style scoped>
.disabled {
  pointer-events: none;
  opacity: .5;
  -moz-opacity: .5;
  /* 黑白色 */
  -webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */
  filter: grayscale(100%);
}
.btn{
  font-weight: bold;
}
/* span > a {
  font-size: .8rem;
} */

:deep().vxe-footer--row{
  background: rgba(250,250,250,.6);
  font-weight: bold;
}
.table-operate{
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
